package main

import (
	"encoding/json"
	"fmt"
	"github.com/hyperledger/fabric-chaincode-go/shim"
	"github.com/hyperledger/fabric-protos-go/peer"
	"reflect"
	"strconv"
	"strings"
	"time"
)

const (
	MedicalRecordString   = "medical-record-key"
	OperationRecordString = "operation-record-key"
	AuditRecordString     = "audit-record-key"
)

// 写到链码里，只保留上链字段
type MedicalRecord struct {
	CaseNumber      string `json:"caseNumber"`      //病例号，上链
	Researcher      string `json:"researcher"`      //研究者，上链
	Organization    string `json:"organization"`    //机构，上链
	OperationType   string `json:"operationType"`   //操作类型
	OperationResult string `json:"operationResult"` //操作结果
	GatherTime      string `json:"gatherTime"`      //采集时间-1，上链
}

// 医疗记录修改历史
type MedicalRecordHistory struct {
	Txid     string        //交易ID
	Txvalue  MedicalRecord //病例当时的值
	Txstatus string        //状态：是否被删除
	Txtime   string        //修改时间
}

type MedicalRecordHistoryArr struct {
	MRH []MedicalRecordHistory `json:"medicalRecordHistory"` //用数组保存
}

// 操作记录，记录在区块链上不可被修改
type OperationRecord struct {
	OperationRecordID string `json:"operationRecordId"` //操作记录ID
	UserID            string `json:"userId"`            //操作者用户
	OrganizationID    string `json:"organizationID"`    //用户组织ID
	DataType          string `json:"dataType"`          //记录类型：操作记录operation
	ActionType        string `json:"actionType"`        //操作类型：访问、修改、删除（Access、Update、Delete）
	MedicalRecordID   string `json:"medicalRecordId"`   //涉及到的医疗记录ID
	OriginalAuthorID  string `json:"originalAuthorId"`  //涉及到的医疗记录创建者
	PatientID         string `json:"patientId"`         //医疗记录涉及到的患者ID
	EntryMethod       string `json:"entryMethod"`       //操作记录的输入方式：自动输入
	IsSuccess         bool   `json:"isSuccess"`         //[fxb] 操作是否成功
	Time              string `json:"time"`              //时间
}

type OperationRecordArr struct {
	OperationRecord []OperationRecord
}

// 审计记录，记录在区块链上不可被修改
type AuditRecord struct {
	AuditRecordID  string `json:"auditRecordId"`  //审计记录ID
	UserID         string `json:"userId"`         //操作者用户（此处为管理员）
	OrganizationID string `json:"organizationID"` //用户组织ID
	DataType       string `json:"dataType"`       //记录类型：审计Audit
	EntryMethod    string `json:"entryMethod"`    //审计记录的输入方式：自动输入
	Time           string `json:"time"`           //时间
}

type SmartContract struct {
}

func (t *SmartContract) Init(stub shim.ChaincodeStubInterface) peer.Response {
	fmt.Println(" ==== Init ====")

	return shim.Success(nil)
}

func (t *SmartContract) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
	// 获取用户意图
	fun, args := stub.GetFunctionAndParameters()

	if fun == "UploadMedicalRecord" {
		return t.UploadMedicalRecord(stub, args)
	} else if fun == "AccessMedicalRecord" {
		return t.AccessMedicalRecord(stub, args)
	} else if fun == "ReadMedicalRecord" {
		return t.ReadMedicalRecord(stub, args)
	} else if fun == "UpdateMedicalRecord" {
		return t.UpdateMedicalRecord(stub, args)
	} else if fun == "DeleteMedicalRecord" {
		return t.DeleteMedicalRecord(stub, args)
	} else if fun == "auditForAllLogs" {
		return t.auditForAllLogs(stub, args)
	} else if fun == "auditForTimeRange" {
		return t.auditForTimeRange(stub, args)
	} else if fun == "auditForUser" {
		return t.auditForUser(stub, args)
	} else if fun == "auditForOrganisation" {
		return t.auditForOrganisation(stub, args)
	} else if fun == "auditForMedicalRecord" {
		return t.auditForMedicalRecord(stub, args)
	} else if fun == "auditForOriginalAuthor" {
		return t.auditForOriginalAuthor(stub, args)
	} else if fun == "auditForPatient" {
		return t.auditForPatient(stub, args)
	} else if fun == "InitUploadMed" {
		return t.InitUploadMed(stub, args)
	} else if fun == "GetInitMedInfo" {
		return t.GetInitMedInfo(stub, args)
	} else if fun == "InitOperationRecord" {
		return t.InitOperationRecord(stub, args)
	}

	return shim.Error("指定的函数名称错误")

}

// 定义函数，用于对数据库中数据的上链操作
// InitUploadMed
func (t *SmartContract) InitUploadMed(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	datainfo := strings.Split(args[0], ";")
	for i := 0; i < len(datainfo); i++ {
		data := strings.Split(datainfo[i], ",")
		m := MedicalRecord{
			CaseNumber:      data[4],
			Researcher:      data[1],
			Organization:    data[2],
			OperationType:   "GenerateData",
			OperationResult: args[1],
			GatherTime:      data[5],
		}
		b, _ := json.Marshal(m)
		err2 := stub.PutState(m.CaseNumber, b)
		fmt.Println(err2)
		if err2 != nil {
			return shim.Error(err2.Error())
		}
		err3 := stub.SetEvent(args[2], []byte{})
		fmt.Println(err3)
		if err3 != nil {
			return shim.Error(err3.Error())
		}
	}
	//data := strings.Split(args[0], ",")
	return shim.Success([]byte("医疗记录添加成功！"))
}

// 读取数据操作
// 仅记录上链，链上不再进行checkaccess，直接把结果写入区块链
// 3个参数，arg[0]=datainfo, org[1]=resultStr,org[2]=eventID
// change By J 0325
// func (t *SmartContract) ReadMedicalRecord(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
func (t *SmartContract) ReadMedicalRecord(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	if len(args) != 3 {
		return shim.Error("----------参数数量不正确----------  Expecting 1")
	}
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	// datainfo[0]=casenumber,datainfo[1]=uid,datainfo[2]=action
	datainfo := strings.Split(args[0], ";")
	m := MedicalRecord{
		CaseNumber:      datainfo[0],
		Researcher:      datainfo[1],
		Organization:    datainfo[3],
		OperationType:   datainfo[2],
		OperationResult: args[1],
		GatherTime:      time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	b, _ := json.Marshal(m)
	err2 := stub.PutState(m.CaseNumber, b)
	if err2 != nil {
		return shim.Error("保存ReadMed信息时发生错误")
	}
	err3 := stub.PutState(m.Researcher, b)
	if err3 != nil {
		return shim.Error("保存ReadMed-Researcher信息时发生错误")
	}
	err4 := stub.SetEvent(args[2], []byte{})
	if err4 != nil {
		return shim.Error(err4.Error())
	}

	/*
		resultStr := args[1]
		eventID := args[2]
		// get EHR
		err := APIstub.PutState(datainfo[0], []byte(datainfo[1]+","+datainfo[2]+","+resultStr))
		if err != nil {
			return shim.Error("保存ReadMed信息时发生错误")
		}
		err2 := APIstub.PutState(datainfo[1], []byte(datainfo[0]+","+datainfo[2]+","+resultStr))
		if err2 != nil {
			return shim.Error("保存ReadMed信息时发生错误")
		}
		// res, err := m.NewResource(b)

		err1 := APIstub.SetEvent(eventID, []byte{})
		if err1 != nil {
			return shim.Error("写入ReadMed事件时发生错误")
		}
	*/
	return shim.Success([]byte("OK"))
}

// 定义函数，用于查看上链结果
// GetInitMedInfo
// input: args[0] : m.CaseNumber
func (t *SmartContract) GetInitMedInfo(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	result0, err0 := stub.GetState(args[0])
	if err0 != nil {
		return shim.Error("医疗记录获取失败！")
	}
	if result0 == nil {
		return shim.Error("医疗记录ID获取失败！")
	}
	var m MedicalRecord
	err1 := json.Unmarshal(result0, &m)
	if err1 != nil {
		return shim.Error("反序列化医疗记录失败！")
	}
	data, _ := json.Marshal(m)
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	m.GatherTime = time.Now().In(loc).Format("2006-01-02 15:04:05")
	m.OperationType = "AccessData"
	b, _ := json.Marshal(m)
	err2 := stub.PutState(args[0], b)
	fmt.Println(err2)
	if err2 != nil {
		return shim.Error(err2.Error())
	}
	err3 := stub.SetEvent(args[2], []byte{})
	fmt.Println(err3)
	if err3 != nil {
		return shim.Error(err3.Error())
	}

	return shim.Success([]byte(data))
}

// 定义函数，用于对数据库中操作记录的上链操作
func (t *SmartContract) InitOperationRecord(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	data := strings.Split(args[0], ",")
	boolvalue, err0 := strconv.ParseBool(data[5])
	if err0 != nil {
		return shim.Error(err0.Error())
	}
	key, errK := stub.CreateCompositeKey(OperationRecordString, []string{data[0], data[1], "test_org", data[3], "test_origin_author", ""})
	if errK != nil {
		return shim.Error("组合键创建失败！")
	}
	o := OperationRecord{
		OperationRecordID: data[0],
		UserID:            data[1],
		OrganizationID:    "test_org_id",
		DataType:          data[3],
		ActionType:        data[4],
		MedicalRecordID:   data[2],
		OriginalAuthorID:  "test_origin_author",
		PatientID:         "test_patient_id",
		EntryMethod:       "auto_init",
		IsSuccess:         boolvalue,
		Time:              data[7],
	}
	b, _ := json.Marshal(o)
	err2 := stub.PutState(key, b)
	fmt.Println(err2)
	if err2 != nil {
		return shim.Error(err2.Error())
	}
	err3 := stub.SetEvent(args[2], []byte{})
	fmt.Println(err3)
	if err3 != nil {
		return shim.Error(err3.Error())
	}
	return shim.Success([]byte("操作记录添加成功！"))
}

// 上传医疗记录, 修改传参为3个参数，arg[0]=datainfo, org[1]=resultStr,org[2]=eventID
// datainfo[0]=casenumber,datainfo[1]=owner,datainfo[2]=org,
func (t *SmartContract) UploadMedicalRecord(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	datainfo := strings.Split(args[0], ";") // datainfo[0]=casenumber,datainfo[1]=owner,datainfo[2]=org,org[1]=resultStr,org[2]=eventID
	r, _ := stub.GetState(datainfo[0])
	if r != nil {
		return shim.Error("医疗记录ID已经存在！")
	}

	m := MedicalRecord{
		CaseNumber:      datainfo[0],
		Researcher:      datainfo[1],
		Organization:    datainfo[2],
		OperationType:   "GenerateData", //此处操作为生成数据
		OperationResult: args[1],
		GatherTime:      time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	b, err1 := json.Marshal(m)
	fmt.Println(err1)
	if err1 != nil {
		return shim.Error(err1.Error())
	}
	err2 := stub.PutState(m.CaseNumber, b)
	fmt.Println(err2)
	if err2 != nil {
		return shim.Error(err2.Error())
	}
	err2_1 := stub.PutState(m.Researcher, b)
	fmt.Println(err2_1)
	if err2_1 != nil {
		return shim.Error(err2_1.Error())
	}
	err3 := stub.SetEvent(args[2], []byte{})
	fmt.Println(err3)
	if err3 != nil {
		return shim.Error(err3.Error())
	}
	return shim.Success([]byte("医疗记录添加成功！"))
}

// 查看医疗记录，及其修改历史
func (t *SmartContract) AccessMedicalRecord(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	// 三个参数 ，casenumber args[0] 和 owner data[1],+ Organization data[2]
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	data := strings.Split(args[0], ",")
	var resultArr MedicalRecordHistoryArr //病例修改历史
	keyInter, err0 := stub.GetHistoryForKey(data[0])
	if err0 != nil {
		return shim.Error("医疗记录获取失败！")
	}
	for keyInter.HasNext() {
		respone, interErr := keyInter.Next()
		if interErr != nil {
			return shim.Error("遍历失败！")
		}
		var m MedicalRecord
		json.Unmarshal(respone.Value, &m)
		mrh := MedicalRecordHistory{
			Txid:     respone.TxId[:10],
			Txvalue:  m,
			Txstatus: strconv.FormatBool(respone.IsDelete),
			Txtime:   time.Unix(respone.Timestamp.Seconds, 0).In(loc).Format("2006-01-02 15:04:05"),
		}
		resultArr.MRH = append(resultArr.MRH, mrh)
	}
	b, err2 := json.Marshal(resultArr)
	if err2 != nil {
		return shim.Error("加工失败！")
	}
	m := MedicalRecord{
		CaseNumber:      data[0],
		Researcher:      data[1],
		Organization:    data[2],
		OperationType:   "TraceData", //此处操作为生成数据
		OperationResult: args[1],
		GatherTime:      time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	newMedicalRecordAsBytes, err5 := json.Marshal(m)
	if err5 != nil {
		return shim.Error("医疗记录加工失败！")
	}
	err6 := stub.PutState(m.CaseNumber, newMedicalRecordAsBytes)
	if err6 != nil {
		return shim.Error("医疗记录历史获取失败！")
	}
	err6_1 := stub.PutState(m.Researcher, newMedicalRecordAsBytes)
	if err6_1 != nil {
		return shim.Error("医疗记录历史获取失败！")
	}
	err7 := stub.SetEvent(args[2], []byte{})
	if err7 != nil {
		return shim.Error(err7.Error())
	}
	return shim.Success(b)
}

// 删除医疗记录
func (t *SmartContract) DeleteMedicalRecord(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	datainfo := strings.Split(args[0], ";") // datainfo[0]=casenumber,datainfo[1]=owner,org[1]=resultStr,org[2]=eventID
	fmt.Println(datainfo)
	result0, err0 := stub.GetState(datainfo[0])
	if err0 != nil {
		return shim.Error("医疗记录获取失败！")
	}
	if result0 == nil {
		return shim.Error("医疗记录ID获取失败！")
	}
	var m MedicalRecord
	err1 := json.Unmarshal(result0, &m)
	if err1 != nil {
		return shim.Error("反序列化医疗记录失败！")
	}
	m.Researcher = datainfo[1]
	m.OperationType = "DeleteData"
	m.OperationResult = args[1]
	newMedicalRecordAsBytes, err2 := json.Marshal(m)
	if err2 != nil {
		return shim.Error("医疗记录加工失败！")
	}
	err3 := stub.PutState(m.CaseNumber, newMedicalRecordAsBytes)
	if err3 != nil {
		return shim.Error("医疗记录删除失败！")
	}
	err3_1 := stub.PutState(m.Researcher, newMedicalRecordAsBytes)
	if err3_1 != nil {
		return shim.Error("医疗记录删除失败！")
	}
	err4 := stub.DelState(datainfo[0])
	if err4 != nil {
		return shim.Error("医疗记录删除失败！")
	}
	err4_1 := stub.DelState(datainfo[1])
	if err4_1 != nil {
		return shim.Error("医疗记录删除失败！")
	}
	err5 := stub.SetEvent(args[2], []byte{})
	if err5 != nil {
		return shim.Error(err5.Error())
	}
	return shim.Success([]byte("医疗记录删除成功！"))
}

// 对医疗记录进行修改（查看合并至该功能）
func (t *SmartContract) UpdateMedicalRecord(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	datainfo := strings.Split(args[0], ";") // datainfo[0]=casenumber,datainfo[1]=owner,org[1]=resultStr,org[2]=eventID
	result0, err0 := stub.GetState(datainfo[0])
	if err0 != nil {
		return shim.Error("医疗记录获取失败！")
	}
	if result0 == nil {
		return shim.Error("医疗记录ID获取失败！")
	}
	var m MedicalRecord
	err1 := json.Unmarshal(result0, &m)
	if err1 != nil {
		return shim.Error("反序列化医疗记录失败！")
	}
	m.Researcher = datainfo[1]
	m.OperationType = "UpdateData"
	newMedicalRecordAsBytes, err2 := json.Marshal(m)
	if err2 != nil {
		return shim.Error("医疗记录加工失败！")
	}
	err3 := stub.PutState(m.CaseNumber, newMedicalRecordAsBytes)
	if err3 != nil {
		return shim.Error("医疗记录修改失败！")
	}
	err3_1 := stub.PutState(m.Researcher, newMedicalRecordAsBytes)
	if err3_1 != nil {
		return shim.Error("医疗记录修改失败！")
	}
	err4 := stub.SetEvent(args[2], []byte{})
	if err4 != nil {
		return shim.Error(err4.Error())
	}
	return shim.Success([]byte("医疗记录修改成功！"))
}

// 获取所有时间的操作记录
func (t *SmartContract) auditForAllLogs(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	if len(args) != 4 {
		return shim.Error("给定的参数个数不符合要求！")
	}
	resultsIterator, err0 := stub.GetStateByPartialCompositeKey(OperationRecordString, []string{})
	if err0 != nil {
		return shim.Error("操作记录获取失败！")
	}
	result1, err1 := stub.GetState(args[0])
	if err1 == nil && result1 != nil {
		return shim.Error("审计记录存在！")
	}
	defer resultsIterator.Close()
	results := OperationRecordArr{}
	for resultsIterator.HasNext() {
		queryResult, err2 := resultsIterator.Next()
		if err2 != nil {
			return shim.Error("迭代失败！")
		}
		var o OperationRecord
		err3 := json.Unmarshal(queryResult.Value, &o)
		if err3 != nil {
			return shim.Error("反序列化操作记录失败！")
		}
		if reflect.TypeOf(o).Name() == "OperationRecord" && o.DataType == "Operation" && (o.ActionType == "Access" || o.ActionType == "Change" || o.ActionType == "Delete") {
			results.OperationRecord = append(results.OperationRecord, o)
		}
	}
	a := AuditRecord{
		AuditRecordID:  args[0],
		UserID:         args[1],
		OrganizationID: args[2],
		DataType:       "Audit",
		EntryMethod:    "Auto",
		Time:           time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	op, err4 := json.Marshal(a)
	if err4 != nil {
		return shim.Error("审计记录加工失败！")
	}
	err5 := stub.PutState(args[0], op)
	if err5 != nil {
		return shim.Error("审计失败！")
	}
	err6 := stub.SetEvent(args[3], []byte{})
	if err6 != nil {
		return shim.Error(err6.Error())
	}
	r, err7 := json.Marshal(results)
	if err7 != nil {
		return shim.Error("结果加工失败！")
	}
	return shim.Success(r)
}

// 获取指定开始结束时间的操作记录
func (t *SmartContract) auditForTimeRange(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	if len(args) != 6 {
		return shim.Error("给定的参数个数不符合要求！")
	}
	resultsIterator, err0 := stub.GetStateByPartialCompositeKey(OperationRecordString, []string{})
	if err0 != nil {
		return shim.Error("操作记录获取失败！")
	}
	result1, err1 := stub.GetState(args[0])
	if err1 == nil && result1 != nil {
		return shim.Error("审计记录存在！")
	}
	defer resultsIterator.Close()
	results := OperationRecordArr{}
	for resultsIterator.HasNext() {
		queryResult, err2 := resultsIterator.Next()
		if err2 != nil {
			return shim.Error("迭代失败！")
		}
		var o OperationRecord
		err3 := json.Unmarshal(queryResult.Value, &o)
		if err3 != nil {
			return shim.Error("反序列化医疗记录失败！")
		}
		if reflect.TypeOf(o).Name() == "OperationRecord" && o.DataType == "Operation" && (o.ActionType == "Access" || o.ActionType == "Change" || o.ActionType == "Delete") {
			formatTime, errT := time.Parse("2006-01-02 15:04:05", o.Time)
			if errT != nil {
				return shim.Error("记录时间转换失败！")
			}
			startTime, errST := time.Parse("2006-01-02 15:04:05", args[3])
			if errST != nil {
				return shim.Error("开始时间转换失败！")
			}
			endTime, errET := time.Parse("2006-01-02 15:04:05", args[4])
			if errET != nil {
				return shim.Error("结束时间转换失败！")
			}
			if formatTime.Unix() >= startTime.Unix() && formatTime.Unix() <= endTime.Unix() {
				// arg[3]：开始时间
				// arg[4]：结束时间
				results.OperationRecord = append(results.OperationRecord, o)
			}
		}
	}
	a := AuditRecord{
		AuditRecordID:  args[0],
		UserID:         args[1],
		OrganizationID: args[2],
		DataType:       "Audit",
		EntryMethod:    "Auto",
		Time:           time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	op, err4 := json.Marshal(a)
	if err4 != nil {
		return shim.Error("审计记录加工失败！")
	}
	err5 := stub.PutState(args[0], op)
	if err5 != nil {
		return shim.Error("审计失败！")
	}
	err6 := stub.SetEvent(args[5], []byte{})
	if err6 != nil {
		return shim.Error(err6.Error())
	}
	r, err7 := json.Marshal(results)
	if err7 != nil {
		return shim.Error("结果加工失败！")
	}
	return shim.Success(r)
}

// 获取指定用户的操作记录
func (t *SmartContract) auditForUser(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	if len(args) != 5 {
		return shim.Error("给定的参数个数不符合要求！")
	}
	resultsIterator, err0 := stub.GetStateByPartialCompositeKey(OperationRecordString, []string{})
	if err0 != nil {
		return shim.Error("操作记录获取失败！")
	}
	result1, err1 := stub.GetState(args[0])
	if err1 == nil && result1 != nil {
		return shim.Error("审计记录存在！")
	}
	defer resultsIterator.Close()
	results := OperationRecordArr{}
	for resultsIterator.HasNext() {
		queryResult, err2 := resultsIterator.Next()
		if err2 != nil {
			return shim.Error("迭代失败！")
		}
		var o OperationRecord
		err3 := json.Unmarshal(queryResult.Value, &o)
		if err3 != nil {
			return shim.Error("反序列化医疗记录失败！")
		}
		if reflect.TypeOf(o).Name() == "OperationRecord" && o.DataType == "Operation" && (o.ActionType == "Access" || o.ActionType == "Change" || o.ActionType == "Delete") {
			if o.UserID == args[3] {
				results.OperationRecord = append(results.OperationRecord, o)
			}
		}
	}
	a := AuditRecord{
		AuditRecordID:  args[0],
		UserID:         args[1],
		OrganizationID: args[2],
		DataType:       "Audit",
		EntryMethod:    "Auto",
		Time:           time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	op, err4 := json.Marshal(a)
	if err4 != nil {
		return shim.Error("审计记录加工失败！")
	}
	err5 := stub.PutState(args[0], op)
	if err5 != nil {
		return shim.Error("审计失败！")
	}
	err6 := stub.SetEvent(args[4], []byte{})
	if err6 != nil {
		return shim.Error(err6.Error())
	}
	r, err7 := json.Marshal(results)
	if err7 != nil {
		return shim.Error("结果加工失败！")
	}
	return shim.Success(r)
}

// 获取关于指定组织的操作记录
func (t *SmartContract) auditForOrganisation(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	if len(args) != 5 {
		return shim.Error("给定的参数个数不符合要求！")
	}
	resultsIterator, err0 := stub.GetStateByPartialCompositeKey(OperationRecordString, []string{})
	if err0 != nil {
		return shim.Error("操作记录获取失败！")
	}
	result1, err1 := stub.GetState(args[0])
	if err1 == nil && result1 != nil {
		return shim.Error("审计记录存在！")
	}
	defer resultsIterator.Close()
	results := OperationRecordArr{}
	for resultsIterator.HasNext() {
		queryResult, err2 := resultsIterator.Next()
		if err2 != nil {
			return shim.Error("迭代失败！")
		}
		var o OperationRecord
		err3 := json.Unmarshal(queryResult.Value, &o)
		if err3 != nil {
			return shim.Error("反序列化医疗记录失败！")
		}
		if reflect.TypeOf(o).Name() == "OperationRecord" && o.DataType == "Operation" && (o.ActionType == "Access" || o.ActionType == "Change" || o.ActionType == "Delete") {
			if o.OrganizationID == args[3] {
				results.OperationRecord = append(results.OperationRecord, o)
			}
		}
	}
	a := AuditRecord{
		AuditRecordID:  args[0],
		UserID:         args[1],
		OrganizationID: args[2],
		DataType:       "Audit",
		EntryMethod:    "Auto",
		Time:           time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	op, err4 := json.Marshal(a)
	if err4 != nil {
		return shim.Error("审计记录加工失败！")
	}
	err5 := stub.PutState(args[0], op)
	if err5 != nil {
		return shim.Error("审计失败！")
	}
	err6 := stub.SetEvent(args[4], []byte{})
	if err6 != nil {
		return shim.Error(err6.Error())
	}
	r, err7 := json.Marshal(results)
	if err7 != nil {
		return shim.Error("结果加工失败！")
	}
	return shim.Success(r)
}

// 获取特定医疗记录的操作记录
func (t *SmartContract) auditForMedicalRecord(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	if len(args) != 5 {
		return shim.Error("给定的参数个数不符合要求！")
	}
	resultsIterator, err0 := stub.GetStateByPartialCompositeKey(OperationRecordString, []string{})
	if err0 != nil {
		return shim.Error("操作记录获取失败！")
	}
	result1, err1 := stub.GetState(args[0])
	if err1 == nil && result1 != nil {
		return shim.Error("审计记录存在！")
	}
	defer resultsIterator.Close()
	results := OperationRecordArr{}
	for resultsIterator.HasNext() {
		queryResult, err2 := resultsIterator.Next()
		if err2 != nil {
			return shim.Error("迭代失败！")
		}
		var o OperationRecord
		err3 := json.Unmarshal(queryResult.Value, &o)
		if err3 != nil {
			return shim.Error("反序列化医疗记录失败！")
		}
		if reflect.TypeOf(o).Name() == "OperationRecord" && o.DataType == "Operation" && (o.ActionType == "Access" || o.ActionType == "Change" || o.ActionType == "Delete") {
			if o.MedicalRecordID == args[3] {
				results.OperationRecord = append(results.OperationRecord, o)
			}
		}
	}
	a := AuditRecord{
		AuditRecordID:  args[0],
		UserID:         args[1],
		OrganizationID: args[2],
		DataType:       "Audit",
		EntryMethod:    "Auto",
		Time:           time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	op, err4 := json.Marshal(a)
	if err4 != nil {
		return shim.Error("审计记录加工失败！")
	}
	err5 := stub.PutState(args[0], op)
	if err5 != nil {
		return shim.Error("审计失败！")
	}
	err6 := stub.SetEvent(args[4], []byte{})
	if err6 != nil {
		return shim.Error(err6.Error())
	}
	r, err7 := json.Marshal(results)
	if err7 != nil {
		return shim.Error("结果加工失败！")
	}
	return shim.Success(r)
}

// 获取特定医疗记录创建者的操作记录
func (t *SmartContract) auditForOriginalAuthor(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	if len(args) != 5 {
		return shim.Error("给定的参数个数不符合要求！")
	}
	resultsIterator, err0 := stub.GetStateByPartialCompositeKey(OperationRecordString, []string{})
	if err0 != nil {
		return shim.Error("操作记录获取失败！")
	}
	result1, err1 := stub.GetState(args[0])
	if err1 == nil && result1 != nil {
		return shim.Error("审计记录存在！")
	}
	defer resultsIterator.Close()
	results := OperationRecordArr{}
	for resultsIterator.HasNext() {
		queryResult, err2 := resultsIterator.Next()
		if err2 != nil {
			return shim.Error("迭代失败！")
		}
		var o OperationRecord
		err3 := json.Unmarshal(queryResult.Value, &o)
		if err3 != nil {
			return shim.Error("反序列化医疗记录失败！")
		}
		if reflect.TypeOf(o).Name() == "OperationRecord" && o.DataType == "Operation" && (o.ActionType == "Access" || o.ActionType == "Change" || o.ActionType == "Delete") {
			if o.OriginalAuthorID == args[3] {
				results.OperationRecord = append(results.OperationRecord, o)
			}
		}
	}
	a := AuditRecord{
		AuditRecordID:  args[0],
		UserID:         args[1],
		OrganizationID: args[2],
		DataType:       "Audit",
		EntryMethod:    "Auto",
		Time:           time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	op, err4 := json.Marshal(a)
	if err4 != nil {
		return shim.Error("审计记录加工失败！")
	}
	err5 := stub.PutState(args[0], op)
	if err5 != nil {
		return shim.Error("审计失败！")
	}
	err6 := stub.SetEvent(args[4], []byte{})
	if err6 != nil {
		return shim.Error(err6.Error())
	}
	r, err7 := json.Marshal(results)
	if err7 != nil {
		return shim.Error("结果加工失败！")
	}
	return shim.Success(r)
}

// 获取指定病人医疗记录的操作记录
func (t *SmartContract) auditForPatient(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("LoadLocation error: " + err.Error())
	}
	if len(args) != 5 {
		return shim.Error("给定的参数个数不符合要求！")
	}
	resultsIterator, err0 := stub.GetStateByPartialCompositeKey(OperationRecordString, []string{})
	if err0 != nil {
		return shim.Error("操作记录获取失败！")
	}
	result1, err1 := stub.GetState(args[0])
	if err1 == nil && result1 != nil {
		return shim.Error("审计记录存在！")
	}
	defer resultsIterator.Close()
	results := OperationRecordArr{}
	for resultsIterator.HasNext() {
		queryResult, err2 := resultsIterator.Next()
		if err2 != nil {
			return shim.Error("迭代失败！")
		}
		var o OperationRecord
		err3 := json.Unmarshal(queryResult.Value, &o)
		if err3 != nil {
			return shim.Error("反序列化医疗记录失败！")
		}
		if reflect.TypeOf(o).Name() == "OperationRecord" && o.DataType == "Operation" && (o.ActionType == "Access" || o.ActionType == "Change" || o.ActionType == "Delete") {
			if o.PatientID == args[3] {
				results.OperationRecord = append(results.OperationRecord, o)
			}
		}
	}
	a := AuditRecord{
		AuditRecordID:  args[0],
		UserID:         args[1],
		OrganizationID: args[2],
		DataType:       "Audit",
		EntryMethod:    "Auto",
		Time:           time.Now().In(loc).Format("2006-01-02 15:04:05"),
	}
	op, err4 := json.Marshal(a)
	if err4 != nil {
		return shim.Error("审计记录加工失败！")
	}
	err5 := stub.PutState(args[0], op)
	if err5 != nil {
		return shim.Error("审计失败！")
	}
	err6 := stub.SetEvent(args[4], []byte{})
	if err6 != nil {
		return shim.Error(err6.Error())
	}
	r, err7 := json.Marshal(results)
	if err7 != nil {
		return shim.Error("结果加工失败！")
	}
	return shim.Success(r)
}

func main() {
	err := shim.Start(new(SmartContract))
	if err != nil {
		fmt.Printf("启动链码时发生错误: %s", err)
	}
}
